﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Gencode.Gengui.Wizzard;
using Gencode.SQLWizz.DataType;
using Gencode.SQLWizz.Database;
using System.Threading;
using System.Resources;
using Gencode.SQLWizz.Properties;

namespace Gencode.SQLWizz.Controls
{
	public partial class CreateDatabase : Gencode.Gengui.Wizzard.WizzardControl
	{
		LogonData logData = null;
		Thread queryThread;
		bool reloadViewForDB = true;

		/// <summary>
		/// delegate to set text ro the listbox from another thread
		/// </summary>
		/// <param name="text"></param>
		delegate void SetTextCallbackDelegate(string text);

		/// <summary>
		/// delegate to continue main thread when querythread is finished
		/// </summary>
		delegate void QueryThreadFinishedDelgate();

		/// <summary>
		/// delegate to reload first view
		/// </summary>
		delegate void QueryReloadView();

		public CreateDatabase(string previousControl, string nextControl, WizzardDialog controler)
			: base(previousControl, nextControl, controler)
		{
			InitializeComponent();
		}



		public override void InitializeWizzardControl()
		{
			//base.InitializeWizzardControl();
			logData = Controler.DataObjects.GetType(typeof(LogonData)) as LogonData;

			if (logData == null || string.IsNullOrEmpty(logData.Database))
			{
				txtDatabase.Enabled = true;
				listOutput.Items.Clear();
				listOutput.Enabled = false;

				//set this control to next control
				nextControl = "newdatabase";
				reloadViewForDB = true;
			}
			else
			{
				lblMsg.Text = Resources.CREATE_DB;
				txtDatabase.Enabled = false;
				listOutput.Enabled = true;
				reloadViewForDB = false;
				//set next control
				nextControl = "end";
				//not alowed to move back so set previousControl to empty
				previousControl = "";

				Controler.ButtonsEnabled = false;
				CreateNewDatabase();
			}

			//reloadView = false;
		}

		private void CreateNewDatabase()
		{
			if (logData != null)
			{
				WZNewDatabase db = new WZNewDatabase(logData, this);
				db.OnError += new ErrorOccured(OnError);
				db.OnOutput += new OutputText(OnOutputText);
				db.OnFinished += new QueryFinished(OnQueryFinished);
				db.OnReload += new ReloadView(OnReloadView);
				queryThread = new Thread(db.CreateNewDatabase);
				queryThread.Start();				
			}
			else
			{ 
				//TODO:
				//show some error
			}

		}

		/// <summary>
		/// will be executed by query thread when the query has finished
		/// </summary>
		private void OnQueryFinished()
		{
			if (this.InvokeRequired)
			{
				QueryThreadFinishedDelgate del = new QueryThreadFinishedDelgate(QueryThreadFinished);
				this.Invoke(del, null);

				queryThread.Abort();
				queryThread = null;
			}
			else
			{
				QueryThreadFinished();
			}
		}

		/// <summary>
		/// will be executed by query thread to move to next object when finished
		/// </summary>
		private void QueryThreadFinished()
		{
			//delay
			Thread.Sleep(1500);
			//enable buttons to move to next view
			Controler.ButtonsEnabled = true;
			Controler.MoveNext();
		}

		/// <summary>
		/// will be executed by query when the view has to be reloaded
		/// </summary>
		public void OnReloadView()
		{
			if (this.InvokeRequired)
			{
				QueryReloadView qrv = new QueryReloadView(ReloadView);
				this.Invoke(qrv, null);
			}
			else
			{
				ReloadView();
			}
		}

		/// <summary>
		/// roloads to the first view
		/// </summary>
		private void ReloadView()
		{
			nextControl = "newdatabase";
			logData.Database = "";
			txtDatabase.Text = "";
			reloadViewForDB = false;
			Controler.ButtonsEnabled = true;
			Controler.MoveNext();
		}

		/// <summary>
		/// displays a messagebox with the erroroutput
		/// </summary>
		/// <param name="message">message to display</param>
		/// <param name="title">title of the messagebox</param>
		private void OnError(string message, string title)
		{
			MessageBox.Show(message, title, MessageBoxButtons.OK);
		}

		
		private void OnOutputText(string text)
		{
			//bool tmp = false;
			//if (text.StartsWith("\r", false, null) || text.StartsWith("\n", false, null))
			//    tmp = true;

			//while (tmp)
			//{
			//    if (text.StartsWith("\r", false, null) || text.StartsWith("\n", false, null))
			//    {
			//        text = text.Substring(1);
			//    }
			//    else
			//        tmp = false;
			//}

			//get acces to control from another thread
			if (listOutput.InvokeRequired)
			{
				// It's on a different thread, so use Invoke.
				SetTextCallbackDelegate d = new SetTextCallbackDelegate(AddText);
				this.Invoke(d, new object[] { text});
			}
			else
			{
				//if not from other thread write text normaly
				AddText(text);
			}
		}

		/// <summary>
		/// delegate method to set text form another thread
		/// </summary>
		/// <param name="text"></param>
		public void AddText(string text)
		{
			listOutput.Items.Add(text);
			
			listOutput.SetSelected(listOutput.Items.Count - 1, true);
			listOutput.SetSelected(listOutput.Items.Count - 1, false);
		}

		protected override void InitLayout()
		{
			base.InitLayout();
		}

		public override bool MoveNext()
		{
			if (reloadViewForDB)
			{
				if (!string.IsNullOrEmpty(txtDatabase.Text))
				{
					logData.Database = txtDatabase.Text;
					return true;
				}
				else
					MessageBox.Show("Bitte geben Sie einen Datenbanknamen an.", "Kein Datenbankname", MessageBoxButtons.OK);

				return false;
			}
			return true;
		}

		public override bool MovePrevious()
		{
			return base.MovePrevious();
		}
	}
}
